package com.chenfan.mcn.clients.baseinfo;

import com.chenfan.common.vo.Response;;
import com.chenfan.mcn.constant.NumberCst;
import com.chenfan.mcn.constant.SeparatorCst;
import com.chenfan.mcn.extension.log.FieldChangeOperateLog;
import com.chenfan.mcn.utils.CommonUtil;
import com.chenfan.mcn.utils.RpcUtil;
import com.chenfan.privilege.api.BaseInfoRemoteServer;
import com.chenfan.mcn.model.common.PageInfo;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author: tangwei
 * Date:     2021/1/10 13:56
 * Description:
 */
@FeignClient(value = "chenfan-cloud-baseinfo",url = "${feign.baseinfo:}")
public interface BaseInfoClient extends BaseInfoRemoteServer {

    /**
     * 新增字段修改操作日志
     *
     * @param fieldChangeOperateLogs {@link FieldChangeOperateLog}
     * @return Response
     */
    @PostMapping("/fieldChange/insertLog")
    Response insertLog(@RequestBody List<FieldChangeOperateLog> fieldChangeOperateLogs);

    /**
     * 获取字典类型下的值集合
     *
     * @param dictProfileCode dictProfileCode
     * @return Response<List < BaseDicts>>
     */
    @GetMapping(value = "dict/value/list", produces = MediaType.APPLICATION_JSON_VALUE)
    Response<List<BaseDicts>> getDictList(@RequestParam("dictProfileCode") String dictProfileCode);

    /**
     * 根据字典值code集合查询对应中文名
     *
     * @param descByCodeDTO {@link com.chenfan.mcn.clients.baseinfo.DescByCodeDTO}
     * @return key: profileCode;dictsCode ,即分号连接两个code
     * value: dictsNameC ,即字典值中文名
     */
    @PostMapping("/dict/getDescByCode")
    Response<Map<String, String>> getDescByCode(@RequestBody DescByCodeDTO descByCodeDTO);

    /**
     * 获取二级字典
     * @param subCode
     * @param profileCode
     * @param dictsStatus
     * @return
     */
    @GetMapping(value = "/dict/getThirdDictCodePageList")
    Response<List<BaseSecondlevelDictsVO>> getThirdDictCodePageList(@RequestParam String subCode, @RequestParam String profileCode, @RequestParam(required = false) Integer dictsStatus);

    /**
     * 获取二级字典
     * @param secondLevelCode
     * @return
     */
    @GetMapping("/dict/getTargetDictNameByCode")
    Response<String> getTargetDictNameByCode(@RequestParam("secondLevelCode") String secondLevelCode);

    /**
     * 根据字典值code集合查询对应字典中英文信息和对应子集信息列表
     *
     * @param profileCodes 字典类型code集合
     * @return
     */
    @PostMapping("/dict/queryCodeListByProfileCodes")
    Response<List<BaseDictNameInfoVo>> queryCodeListByProfileCodes(@RequestBody List<String> profileCodes);

    /**
     * 获取客户信息
     *
     * @param baseCustomer {@link BaseCustomer}
     * @return {@link BaseCustomerDetailVO}
     */
    @PostMapping(value = "/baseCustomer/selectCustomer")
    Response<List<BaseCustomerDetailVO>> selectCustomer(@RequestBody BaseCustomer baseCustomer);

    /**
     * 获取MCN客户档案
     *
     * @return
     */
    @GetMapping(value = "/baseCustomer/mcnListAll")
    Response<List<BaseCustomer>> mcnListAll();

    /**
     * 批量新建mcn客户档案
     * @param customers
     * @return
     */
    @PostMapping(value = "/baseCustomer/addList")
    Response<List<BaseCustomer>> addList(@RequestBody List<BaseCustomer> customers);

    /**
     * 批量获取客户信息
     *
     * @param ids {@link List}
     * @return {@link Map}
     */
    @PostMapping(value = "/baseCustomer/getMcnCustomerByIds")
    Response<Map<Long, BaseCustomer>> getMcnCustomerByIds(@RequestBody List<Long> ids);

    /**
     * 获取操作日志
     *
     * @param logDTO {@link LogDTO}
     * @return {@link PageInfo<FieldChangeOperateLog>}
     */
    @PostMapping(value = "/fieldChange/getlog")
    Response<PageInfo<FieldChangeOperateLog>> getLog(@RequestBody LogDTO logDTO);

    /**
     * 根据id获取mcn客户开票信息
     *
     * @param id {@link Long}
     * @return Response<BaseCustomerBillingVO>
     */
    @GetMapping("/baseCustomer/getBillingsById")
    Response<BaseCustomerBillingVO> getBillingsInfoById(@RequestParam Long id);

    /**
     * 根据id集合查询第三方账号列表
     *
     * @param ids {@link List}
     * @return Response<List < ThirdPayAccount>>
     */
    @PostMapping("/thirdPay/getByIds")
    Response<List<ThirdPayAccount>> getByIds(@RequestBody List<Long> ids);

    /**
     * 获取客户id
     *
     * @param names 客户名字集合
     * @return 对应数据
     */
    @PostMapping(value = "/baseCustomer/getCustomerIdByName")
    Response<Map<String, Long>> getCustomerIdByName(@RequestBody List<String> names);

    /**
     * 第三方账号详情
     *
     * @param id {@link Long}
     * @return Response<ThirdPayAccount>
     */
    @GetMapping("/thirdPay/detail")
    Response<ThirdPayAccount> getDetail(@RequestParam Long id);

    /**
     * 模糊搜索mcn客户
     *
     * @param mcnCustomerSearchDTO {@link McnCustomerSearchDTO}
     * @return List<BaseCustomer>
     */
    @PostMapping("/baseCustomer/search/mcnCustomer")
    Response<List<BaseCustomer>> searchMcnCustomer(@RequestBody McnCustomerSearchDTO mcnCustomerSearchDTO);

    /**
     * 新增开票信息
     *
     * @param baseCustomerBilling {@link BaseCustomerBillingVO}
     * @return Integer
     */
    @PostMapping("/baseCustomer/singleCustomerBilling/add")
    Response<Long> addSingleBilling(@RequestBody BaseCustomerBillingVO baseCustomerBilling);

    /**
     * 获取mcn客户系统默认开票信息
     *
     * @param customerCode {@link String}
     * @param customerName {@link String}
     * @return BaseCustomerBillingVO
     */
    @GetMapping("/baseCustomer/getDefaultBillings")
    Response<BaseCustomerBillingVO> getDefaultBillings(@RequestParam String customerCode, @RequestParam String customerName);

    /**
     * 查询所有第三方打款方式
     * @return
     */
    @GetMapping("/thirdPay/getAccount")
    Response<List<AccountInfoVO>> getThirdPayAllAccount();

    /**
     * 第三方账号详情
     *
     * @param id {@link Long}
     * @return Response<ThirdPayAccount>
     */
    @GetMapping("/thirdPay/detail")
    Response<ThirdPayAccount> getThirdPayById(@RequestParam Long id);

    /**
     *用户数据转移
     * @param dto
     * @return
     */
    @PostMapping("/baseCustomer/userDataTransfer")
    Response<BaseInfoDataMoveVO> userDataTransfer(@RequestBody BaseInfoDataMoveDTO dto);

    /**
     * 用户数据转移补偿
     * @param taskCode
     * @return
     */
    @GetMapping("/baseCustomer/userDataTransferReturn")
    Response<Object> userDataTransferReturn(@RequestParam String taskCode);

    /**
     * 批量新增客户开票信息
     *
     * @param billingDTOList 新增请求参数
     * @return Object
     */
    @PostMapping(value = "/baseCustomerBilling/batchAddBaseCustomerBilling")
    Response<Object> batchAddBaseCustomerBilling(@RequestBody List<BaseCustomerBillingDTO> billingDTOList) ;

    /**
     * 根据对应查询条件查询客户档案开票相关信息
     *
     * @param queryVO 查询条件信息
     * @return List<BaseCustomerBillingDTO>
     */
    @PostMapping(value = "/baseCustomerBilling/queryBillingsByCondition")
    Response<PageInfo<BaseCustomerBillingDTO>> queryBillingsByCondition(@RequestBody BaseCustomerBillingQueryVO queryVO);



    /**
     * 根据id获取mcn客户开票信息
     *
     * @param ids {@link List<Long>}
     * @return Response<BaseCustomerBillingVO>
     */
    @PostMapping("/baseCustomerBilling/queryBillingsByBillingIds")
    Response<List<BaseCustomerBillingVO>> queryBillingsByBillingIds(@RequestBody List<Long> ids);

    /**
     * 根据客户账户id获取客户账户信息
     *
     * @param id {@link Long}
     * @return Response<BaseCustomerAccountVO>
     */
    default Response<BaseCustomerAccountVO> getCustomerAccountById(@RequestParam Long id) {
        Response<BaseCustomerBillingVO> response = this.getBillingsInfoById(id);
        BaseCustomerBillingVO baseCustomerBilling = RpcUtil.getObjException(response, "获取客户账户信息失败！");
        BaseCustomerAccountVO baseCustomerAccount = new BaseCustomerAccountVO();
        if(Objects.nonNull(baseCustomerBilling)) {
            baseCustomerAccount.setAccountId(baseCustomerBilling.getBillingId());
            //收款户名=开票抬头
            baseCustomerAccount.setAccountName(baseCustomerBilling.getInvoiceTitle());
            baseCustomerAccount.setType(baseCustomerBilling.getAccountType());
            baseCustomerAccount.setBankCity(baseCustomerBilling.getBankCity());
            baseCustomerAccount.setBankProvince(baseCustomerBilling.getBankProvince());
            baseCustomerAccount.setBankName(baseCustomerBilling.getBillingBank());
            baseCustomerAccount.setBankNameBranch(baseCustomerBilling.getBankNameBranch());
            //收款卡号=开户账户
            baseCustomerAccount.setCardNumber(baseCustomerBilling.getBillingAccount());
            baseCustomerAccount.setCustomerCode(baseCustomerBilling.getCustomerCode());
            baseCustomerAccount.setIdNumber(baseCustomerBilling.getIdNumber());
            baseCustomerAccount.setPhoneNumber(baseCustomerBilling.getBillingTel());
            baseCustomerAccount.setRemark(baseCustomerBilling.getRemark());
        }
        return new Response<>(response.getCode(), response.getMessage(), baseCustomerAccount);
    }

    /**
     * 根据客户账户id集合获取客户账户信息
     *
     * @param ids {@link List<Long>}
     * @return List<BaseCustomerAccount>
     */
    default  Response<List<BaseCustomerAccount>> getCustomerAccountByIds(@RequestBody List<Long> ids) {
        Response<List<BaseCustomerBillingVO>> response = this.queryBillingsByBillingIds(ids);
        return new Response<>(
                response.getCode(),
                response.getMessage(),
                CommonUtil.defaultList(response.getObj()).stream().map(e -> {
                    BaseCustomerAccount baseCustomerAccount = new BaseCustomerAccount();
                    baseCustomerAccount.setAccountId(e.getBillingId());
                    //收款户名=开票抬头
                    baseCustomerAccount.setAccountName(e.getInvoiceTitle());
                    baseCustomerAccount.setType(e.getAccountType());
                    baseCustomerAccount.setBankCity(e.getBankCity());
                    baseCustomerAccount.setBankProvince(e.getBankProvince());
                    baseCustomerAccount.setBankName(e.getBillingBank());
                    baseCustomerAccount.setBankNameBranch(e.getBankNameBranch());
                    //收款卡号=开户账户
                    baseCustomerAccount.setCardNumber(e.getBillingAccount());
                    baseCustomerAccount.setCustomerCode(e.getCustomerCode());
                    baseCustomerAccount.setIdNumber(e.getIdNumber());
                    baseCustomerAccount.setPhoneNumber(e.getBillingTel());
                    baseCustomerAccount.setRemark(e.getRemark());
                    return baseCustomerAccount;
                }).collect(Collectors.toList())
        );
    }

    /**
     * 所有账户信息
     * @return
     */
    @GetMapping("/baseCustomer/customer/allAccountInfo")
    Response<List<CustomerAccountOrBillingInfoResp>> allAccountInfo();

    /**
     * 获取二级字典
     * @param dictProfileCode
     * @param dictsStatus
     * @return
     */
    @GetMapping(value = "/dict/value/getSecondDictList", produces = MediaType.APPLICATION_JSON_VALUE)
    Response<List<BaseDictsVO>> getSecondDictList(@RequestParam String dictProfileCode, @RequestParam Boolean dictsStatus);


    /**
     * 获取全部发布平台字典Map（重复的话优先取启用）
     * @param dictType 字典类型
     * @return
     */
    default Map<String, Map<String, String>> getAllSecondlevelDictMap(String dictType) {
        List<BaseDictsVO> dictList = this.getSecondDictList(dictType, false).getObj();
        Map<String, Map<String, String>> dictMap = CommonUtil.defaultList(dictList).stream().collect(Collectors.toMap(k -> k.getDictsCode(), v ->
                CommonUtil.defaultList(v.getThirdDictList()).stream().sorted(Comparator.comparing(BaseSecondlevelDictsVO::getDictsStatus))
                        .collect(HashMap::new, (n, o) -> n.putIfAbsent(o.getSecondlevelCode(), o.getSecondlevelDictsNameC()), Map::putAll)
        ));
        return dictMap;
    }


    /**
     * 获取已启用的发布平台字典Map（重复的话优先取启用）
     * @param dictType
     * @return
     */
    default Map<String, Map<String, String>> getEnabledSecondlevelDictMap(String dictType) {
        List<BaseDictsVO> dictList = this.getSecondDictList(dictType, false).getObj();
        Map<String, Map<String, String>> dictMap = CommonUtil.defaultList(dictList).stream().collect(Collectors.toMap(k -> k.getDictsCode(), v ->
                CommonUtil.defaultList(v.getThirdDictList()).stream().sorted(Comparator.comparing(BaseSecondlevelDictsVO::getDictsStatus))
                        .filter(e ->  NumberCst.ZERO.equals(e.getDictsStatus()))
                        .collect(HashMap::new, (n, o) -> n.putIfAbsent(o.getSecondlevelCode(), o.getSecondlevelDictsNameC()), Map::putAll)
        ));
        return dictMap;
    }

    /**
     * 获取字典名称
     * @param profileCode
     * @param dictCode
     * @return
     */
    default String getDictName(String profileCode, String dictCode) {
        Map<String, String> stringMap = this.getDescByCode(new DescByCodeDTO()
                .setDictsCodes(Collections.singletonList(dictCode)).setProfileCodes(Collections.singletonList(profileCode))).getObj();
        return CommonUtil.getMapValue(stringMap, profileCode + SeparatorCst.SEMICOLON + dictCode);
    }
}